package com.zzvcom.template.hibernate;

import java.io.Serializable;

import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.springframework.util.Assert;

import com.zzvcom.template.ResultPage;

/**
 * 封装SpringSide扩展功能的Hibernat范型基类. 扩展功能包括分页查询,按属性过滤条件列表查询等.
 * 可在Service层直接使用,也可以扩展范型DAO子类使用.
 * 
 * @param <T> DAO操作的对象类型
 * @param <PK> 主键类型
 * @author faylai
 */
public class DefaultDao<T, PK extends Serializable> extends BaseDao<T, PK>
{
    /**
     * 用于扩展的DAO子类使用的构造函数. 通过子类的范型定义取得对象类型Class. eg. public class UserDao extends
     * SimpleHibernateDao<User, Long>
     */
    public DefaultDao()
    {
        super();
    }

    /**
     * 用于Service层直接使用SimpleHibernateDAO的构造函数. eg. SimpleHibernateDao<User,
     * Long> userDao = new SimpleHibernateDao<User, Long>(sessionFactory,
     * User.class);
     */
    public DefaultDao(SessionFactory sessionFactory, Class<T> entityClass)
    {
        super(sessionFactory, entityClass);
    }



    /**
     * 按DetachedCriteria分页查询. 不支持自动获取总结果数,需用户另行执行查询.
     * 
     * @param page 分页参数.仅支持pageSize 和firstResult,忽略其他参数.
     */
    @SuppressWarnings("unchecked")
    public ResultPage getResultPageByDetachedCriteria(final ResultPage page)
    {
        Assert.notNull(page);
        
        if (page.getCurrentPage() < 1)
        {
            page.setCurrentPage(1);
        }      
        int totalRecord = countByCriteria(page.getDetachedCriteria());// 查询总记录数
        page.setTotalRecord(totalRecord);
        if (page.getPageSize() < 1)
        {
            page.setPageSize(ResultPage.PAGE_SIZE);

        }
        int totalPage = totalRecord % page.getPageSize();
        if(totalPage==0)
        {
            totalPage=totalRecord / page.getPageSize();
        }
        else
        {
            totalPage=totalRecord / page.getPageSize() + 1;
        }
        page.setTotalPage(totalPage);   

        if (page.getCurrentPage() > page.getTotalPage())
        {
            page.setCurrentPage(page.getTotalPage());
        }
      
        for (Order o : page.getOrders())
        {
            page.getDetachedCriteria().addOrder(o);// 附加排序
        }
        
        page.setResult(getListByCriteria(page.getDetachedCriteria(), page.getFirstResult(),page.getPageSize()));
        return page;
    }
    
    /**
     * 按hql分页查询. 不支持自动获取总结果数,需用户另行执行查询.
     * 
     * @param page 分页参数.仅支持pageSize 和firstResult,忽略其他参数.
     */
    @SuppressWarnings("unchecked")
    public ResultPage getResultPageByHQL(final ResultPage page)
    {
        Assert.notNull(page);
        
        if (page.getCurrentPage() < 1)
        {
            page.setCurrentPage(1);
        } 
        
        int totalRecord = Integer.valueOf(queryUniqueByHQL(page.getCountHql(), page.getHqlParams()).toString());// 查询总记录数
        page.setTotalRecord(totalRecord);
        if (page.getPageSize() < 1)
        {
            page.setPageSize(ResultPage.PAGE_SIZE);

        }
        int totalPage = totalRecord % page.getPageSize();
        if(totalPage==0)
        {
            totalPage=totalRecord / page.getPageSize();
        }
        else
        {
            totalPage=totalRecord / page.getPageSize() + 1;
        }
        page.setTotalPage(totalPage);   

        if (page.getCurrentPage() > page.getTotalPage())
        {
            page.setCurrentPage(page.getTotalPage());
        }
      
        for (Order o : page.getOrders())
        {
            page.getDetachedCriteria().addOrder(o);// 附加排序
        }
        
        page.setResult(this.queryByHQL(page.getHql(), page.getFirstResult(),page.getPageSize(),page.getHqlParams()));
        return page;
    }   
    

}
